home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet multimedia / Animacje, filmy i prezentacje / Modelowanie 3D / K-3D 0.6.5.0 / k3d-all-in-one-setup-0.6.5.0.exe / k3d-setup-0.6.5.0.exe / share / shaders / k3d_patterns.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-03-17  |  6.8 KB  |  247 lines

  1. /************************************************************************
  2.  * patterns.h - Some handy functions for various patterns.  Wherever
  3.  *              possible, antialiased versions will also be given.
  4.  *
  5.  * Author: Larry Gritz (gritzl@acm.org)
  6.  *
  7.  * Reference:
  8.  *   _Advanced RenderMan: Creating CGI for Motion Picture_, 
  9.  *   by Anthony A. Apodaca and Larry Gritz, Morgan Kaufmann, 1999.
  10.  *
  11.  * $Revision: 1.2 $    $Date: 2006/03/17 16:00:41 $
  12.  *
  13.  ************************************************************************/
  14.  
  15.  
  16.  
  17. #ifndef PATTERNS_H
  18. #define PATTERNS_H 1
  19.  
  20. #include "k3d_filterwidth.h"
  21. #include "k3d_functions.h"
  22.  
  23.  
  24.  
  25. /* Antialiased abs().  
  26.  * Compute the box filter of abs(t) from x-dx/2 to x+dx/2.
  27.  * Hinges on the realization that the indefinite integral of abs(x) is 
  28.  * sign(x) * 1/2 x*x;
  29.  */
  30. float filteredabs (float x, dx)
  31. {
  32.     float integral (float t) {
  33.     return sign(t) * 0.5 * t*t;
  34.     }
  35.  
  36.     float x0 = x - 0.5*dx;
  37.     float x1 = x0 + dx;
  38.     return (integral(x1) - integral(x0)) / dx;
  39. }
  40.  
  41.  
  42.  
  43.  
  44. /* Antialiased smoothstep(e0,e1,x).  
  45.  * Compute the box filter of smoothstep(e0,e1,t) from x-dx/2 to x+dx/2.
  46.  * Strategy: divide domain into 3 regions: t < e0, e0 <= t <= e1,
  47.  * and t > e1.  Region 1 has integral 0.  Region 2 is computed by
  48.  * analytically integrating smoothstep, which is -2t^3+3t^2.  Region 3
  49.  * is trivially 1.
  50.  */
  51. float filteredsmoothstep (float e0, e1, x, dx)
  52. {
  53.     float integral (float t) {
  54.     return -0.5*t*t * (t*t + t);
  55.     }
  56.  
  57.     /* Compute x0, x1 bounding region of integration, and normalize so that
  58.      * e0==0, e1==1
  59.      */
  60.     float edgediff = e1 - e0;
  61.     float x0 = (x-e0)/edgediff;
  62.     float fw = dx / edgediff;
  63.     x0 -= 0.5*fw;
  64.     float x1 = x0 + fw;
  65.  
  66.     /* Region 1 always contributes nothing */
  67.     float int = 0;
  68.     /* Region 2 - compute integral in region between 0 and 1 */
  69.     if (x0 < 1 && x1 > 0)
  70.     int += integral(min(x1,1)) - integral(max(x0,0));
  71.     /* Region 3 - is 1.0 */
  72.     if (x1 > 1)
  73.     int += x1-max(1,x0);
  74.     return int / fw;
  75. }
  76.  
  77.  
  78.  
  79. /* A 1-D pulse pattern:  return 1 if edge0 <= x <= edge1, otherwise 0 */
  80. float pulse(float edge0, edge1, x)
  81. {
  82.     return step(edge0,x) - step(edge1,x);
  83. }
  84.  
  85.  
  86.  
  87. float filteredpulse (float edge0, edge1, x, dx)
  88. {
  89.     float x0 = x - dx/2;
  90.     float x1 = x0 + dx;
  91.     return max (0, (min(x1,edge1)-max(x0,edge0)) / dx);
  92. }
  93.  
  94.  
  95.  
  96. /* A pulse train: a signal that repeats with a given period, and is
  97.  * 0 when 0 <= mod(x,period) < edge, and 1 when mod(x,period) > edge.
  98.  */
  99. float pulsetrain (float edge, period, x)
  100. {
  101.     return pulse (edge, period, mod(x,period));
  102. }
  103.  
  104.  
  105. /* Filtered pulse train: it's not as simple as just returning the mod
  106.  * of filteredpulse -- you have to take into account that the filter may
  107.  * cover multiple pulses in the train.
  108.  * Strategy: consider the function that is the integral of the pulse
  109.  * train from 0 to x. Just subtract!
  110.  */
  111. float filteredpulsetrain (float edge, period, x, dx)
  112. {
  113.     /* First, normalize so period == 1 and our domain of interest is > 0 */
  114.     float w = dx/period;
  115.     float x0 = x/period - w/2;
  116.     float x1 = x0+w;
  117.     float nedge = edge / period;   /* normalized edge value */
  118.  
  119.     /* Definite integral of normalized pulsetrain from 0 to t */
  120.     float integral (float t) { 
  121.         extern float nedge;
  122.         return ((1-nedge)*floor(t) + max(0,t-floor(t)-nedge));
  123.     }
  124.  
  125.     /* Now we want to integrate the normalized pulsetrain over [x0,x1] */
  126.     return (integral(x1) - integral(x0)) / w;
  127. }
  128.  
  129.  
  130.  
  131. float
  132. smoothpulse (float e0, e1, e2, e3, x)
  133. {
  134.     return smoothstep(e0,e1,x) - smoothstep(e2,e3,x);
  135. }
  136.  
  137.  
  138. float
  139. filteredsmoothpulse (float e0, e1, e2, e3, x, dx)
  140. {
  141.     return filteredsmoothstep(e0,e1,x,dx) - filteredsmoothstep(e2,e3,x,dx);
  142. }
  143.  
  144.  
  145.  
  146. /* A pulse train of smoothsteps: a signal that repeats with a given
  147.  * period, and is 0 when 0 <= mod(x/period,1) < edge, and 1 when
  148.  * mod(x/period,1) > edge.  
  149.  */
  150. float smoothpulsetrain (float e0, e1, e2, e3, period, x)
  151. {
  152.     return smoothpulse (e0, e1, e2, e3, mod(x,period));
  153. }
  154.  
  155.  
  156.  
  157. /* varyEach takes a computed color, then tweaks each indexed item
  158.  * separately to add some variation.  Hue, saturation, and lightness
  159.  * are all independently controlled.  Hue adds, but saturation and
  160.  * lightness multiply.
  161.  */
  162. color varyEach (color Cin; float index, varyhue, varysat, varylum;)
  163. {
  164.     /* Convert to "hsl" space, it's more convenient */
  165.     color Chsl = ctransform ("hsl", Cin);
  166.     float h = comp(Chsl,0), s = comp(Chsl,1), l = comp(Chsl,2);
  167.     /* Modify Chsl by adding Cvary scaled by our separate h,s,l controls */
  168.     h += varyhue * (cellnoise(index+3)-0.5);
  169.     s *= 1 - varysat * (cellnoise(index-14)-0.5);
  170.     l *= 1 - varylum * (cellnoise(index+37)-0.5);
  171.     Chsl = color (mod(h,1), clamp(s,0,1), clamp(l,0,1));
  172.     /* Clamp hsl and transform back to rgb space */
  173.     return ctransform ("hsl", "rgb", clamp(Chsl,color 0, color 1));
  174. }
  175.  
  176.  
  177.  
  178. /* Given 2-D texture coordinates ss,tt and their filter widths ds, dt,
  179.  * and the width and height of the grooves between tiles (assuming that
  180.  * tile spacing is 1.0), figure out which (integer indexed) tile we are
  181.  * on and what coordinates (on [0,1]) within our individual tile we are
  182.  * shading.
  183.  */
  184. float
  185. tilepattern (float ss, tt, ds, dt;
  186.          float groovewidth, grooveheight;
  187.          output float swhichtile, twhichtile;
  188.          output float stile, ttile;)
  189. {
  190.     swhichtile = floor (ss);
  191.     twhichtile = floor (tt);
  192.     stile = ss - swhichtile;
  193.     ttile = tt - twhichtile;
  194.  
  195.     return filteredpulsetrain (groovewidth, 1, ss+groovewidth/2, ds)
  196.              * filteredpulsetrain (grooveheight, 1, tt+grooveheight/2, dt);
  197. }
  198.  
  199.  
  200.  
  201. /* basic brick tiling pattern --
  202.  *   inputs:
  203.  *      x, y                    positions on a 2-D surface
  204.  *      tilewidth, tileheight   dimensions of each tile
  205.  *      rowstagger              how much does each row stagger relative to
  206.  *                                   the previous row
  207.  *      rowstaggervary          how much should rowstagger randomly vary
  208.  *      jaggedfreq, jaggedamp   adds noise to the edge between the tiles
  209.  *   outputs:
  210.  *      row, column             index which tile the sample is in
  211.  *      xtile, ytile            position within this tile (0-1)
  212.  */
  213. void basicbrick (float x, y;
  214.         uniform float tilewidth, tileheight;
  215.         uniform float rowstagger, rowstaggervary;
  216.         uniform float jaggedfreq, jaggedamp;
  217.         output float column, row;
  218.         output float xtile, ytile;
  219.     )
  220. {
  221.     point PP;
  222.     float scoord = x, tcoord = y;
  223.  
  224.     if (jaggedamp != 0.0) {
  225.     /* Make the shapes of the bricks vary just a bit */
  226.     PP = point noise (x*jaggedfreq/tilewidth, y*jaggedfreq/tileheight);
  227.     scoord += jaggedamp * xcomp (PP);
  228.     tcoord += jaggedamp * ycomp (PP);
  229.     }
  230.  
  231.     xtile = scoord / tilewidth;
  232.     ytile = tcoord / tileheight;
  233.     row = floor (ytile);   /* which brick row? */
  234.  
  235.     /* Shift the columns randomly by row */
  236.     xtile += mod (rowstagger * row, 1);
  237.     xtile += rowstaggervary * (noise (row+0.5) - 0.5);
  238.  
  239.     column = floor (xtile);
  240.     xtile -= column;
  241.     ytile -= row;
  242. }
  243.  
  244.  
  245.  
  246. #endif /* defined(PATTERNS_H) */
  247.